/**
 * 
 */
package edu.umd.clip.lm.util.tree;

import java.util.*;
/**
 * @author Denis Filimonov <den@cs.umd.edu>
 *
 */
public class AnyaryTree <T> {
	private HashSet<AnyaryTree<T>> children = null;
	private T payload;
	private AnyaryTree<T> parent;
	
	public AnyaryTree(T payload) {
		this.payload = payload;
	}
	
	public boolean isLeaf() {
		return children == null || children.size() == 0;
	}
	
	public void addChild(AnyaryTree<T> child) {
		if (children == null) children = new HashSet<AnyaryTree<T>>();
		children.add(child);
		child.parent = this;
	}

	public HashSet<AnyaryTree<T>> getChildren() {
		return children;
	}

	/**
	 * @param children the children to set
	 */
	public void setChildren(HashSet<AnyaryTree<T>> children) {
		this.children = children;
	}

	public T getPayload() {
		return payload;
	}
	
	/**
	 * @param payload the payload to set
	 */
	public void setPayload(T payload) {
		this.payload = payload;
	}

	public AnyaryTree<T> searchPreorder(AnyaryTreeFinder<T> finder) {
		if (finder.apply(this)) return this;
		if (children != null) {
			for(AnyaryTree<T> child : children) {
				AnyaryTree<T> result = child.searchPreorder(finder);
				if (result != null) return result;
			}
		}
		return null;
	}
	
	public AnyaryTree<T> searchPostorder(AnyaryTreeFinder<T> finder) {
		if (children != null) {
			for(AnyaryTree<T> child : children) {
				AnyaryTree<T> result = child.searchPreorder(finder);
				if (result != null) return result;
			}
		}
		return finder.apply(this) ? this : null;
	}

	/**
	 * @return the parent
	 */
	public AnyaryTree<T> getParent() {
		return parent;
	}
	
}
